﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Net;
using System.Xml;
using System.Xml.XPath;
using System.IO;

using NUnit.Framework;
using Twitter.Net;
using Twitter.Net.Status;

namespace Twitter.Net.Tests
{
	[TestFixture]
	public class TwitterProviderTests
	{
		static string username = "tweet_api";
		static string password = "password";

		[TestFixture]
		public class StatusProviderTests
		{
			[Test]
			public void CanDestroyStatus()
			{
				StatusProvider provider = new StatusProvider(username, password);

				//start with updating the status
				string status = string.Format("Updated at {0}", DateTime.Now);
				string data = provider.UpdateStatus(ResponseFormat.xml, status);
				Assert.IsTrue(data.StartsWith("<?xml"), "XML was not returned");

				//get the status ID
				XPathNavigator nav = GetNode(data, "/status/id");
				string val = nav.InnerXml;
				int statusID = int.Parse(val);

				//destroy the status
				provider.DestroyStatus(ResponseFormat.xml, statusID);
				Assert.IsTrue(data.Contains("<status>"), "Destroy failed");
			}

			[Test]
			public void CanGetFriendsTimeline()
			{
				StatusProvider provider = new StatusProvider(username, password);
				string data = provider.GetFriendsTimeline(ResponseFormat.xml);
				Assert.IsTrue(data.StartsWith("<?xml"), "XML was not returned");
			}

			[Test]
			public void CanGetPublicTimeline()
			{
				StatusProvider provider = new StatusProvider(username, password);
				string data = provider.GetPublicTimeline(ResponseFormat.xml);
				Assert.IsTrue(data.StartsWith("<?xml"), "XML was not returned");
			}

			[Test]
			public void CanGetReplies()
			{
				StatusProvider provider = new StatusProvider(username, password);
				string data = provider.GetReplies(ResponseFormat.xml);
				Assert.IsTrue(data.StartsWith("<?xml"), "XML was not returned");
			}

			[Test]
			public void CanGetStatus()
			{
				StatusProvider provider = new StatusProvider(username, password);
				string data = provider.GetStatus(ResponseFormat.xml, 802320712);
				Assert.IsTrue(data.StartsWith("<?xml"), "XML was not returned");
			}

			[Test]
			public void CanGetUserTimeline()
			{
				StatusProvider provider = new StatusProvider(username, password);
				string data = provider.GetUserTimeline(ResponseFormat.xml);
				Assert.IsTrue(data.StartsWith("<?xml"), "XML was not returned");
			}

			[Test]
			public void CanUpdateStatus()
			{
				StatusProvider provider = new StatusProvider(username, password);
				string status = string.Format("Updated at {0}", DateTime.Now);
				string data = provider.UpdateStatus(ResponseFormat.xml, status);
				Assert.IsTrue(data.StartsWith("<?xml"), "XML was not returned");
			}
		}

		[Test]
		public void CanVerifyCredentials()
		{
			HttpStatusCode statusCode;
			TwitterProvider provider = new TwitterProvider(username, password);
			bool verified = provider.CredentialsAreValid(out statusCode);

			Assert.IsTrue(verified, "credentials could not be verified: " + statusCode.ToString());
		}

		#region Helper methods


		static internal protected XPathNavigator GetNode(string xml, string nodePath)
		{
			XmlDocument doc = GetXmlDoc(xml);
			XPathNavigator nav = doc.CreateNavigator();
			return nav.SelectSingleNode(nodePath);
		}

		static internal protected XPathNodeIterator GetNodes(string xml, string nodePath)
		{
			XmlDocument doc = GetXmlDoc(xml);
			//XmlNamespaceManager nsMan = GetNamespaceManager(doc);
			XPathNavigator nav = doc.CreateNavigator();
			XPathExpression expr1 = nav.Compile(nodePath);
			//expr1.SetContext(nsMan);
			XPathNodeIterator iter = nav.Select(expr1);
			return iter;
		}

		/// <summary>
		/// Gets an XmlDocument from the given xml string.
		/// </summary>
		/// <param name="xml">The XML.</param>
		/// <returns></returns>
		static internal protected XmlDocument GetXmlDoc(string xml)
		{
			XmlDocument doc = new XmlDocument();
			doc.PreserveWhitespace = false;
			doc.LoadXml(xml.Trim());
			return doc;
		}

		#endregion Helper methods
	}
}
